package cool.webstudy.admin.utils.crypto;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Hex;
import org.apache.tomcat.util.codec.binary.Base64;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;

/**
 *
 * @author 莫振双
 * @date 2024/7/13 17:56
 * @description: AES加解密工具
 */
@Slf4j
public class AESUtil {
    private final static String AES_FLAG = "AES";

    /**
     * mysql 加密一致的SecretKeySpec
     *
     * @param key
     * @return
     */
    private static SecretKeySpec general(String key) {

        try {
            byte[] finalKey = new byte[16];
            int i = 0;
            for (byte b : key.getBytes(StandardCharsets.UTF_8)) {
                finalKey[i++ % 16] ^= b;
            }
            return new SecretKeySpec(finalKey, AES_FLAG);
        } catch (Exception e) {
            log.error("Aes加解密异常gener,", e);
        }
        return null;
    }


    public static SecretKeySpec generateMysqlAesKey(final String key, final String encoding) {
        try {
            final byte[] finalKey = new byte[16];
            int i = 0;
            for (byte b : key.getBytes(encoding)) {
                finalKey[i++ % 16] ^= b;
            }
            return new SecretKeySpec(finalKey, AES_FLAG);
        } catch (UnsupportedEncodingException e) {
            log.error("Aes加解密异常generateMysqlAesKey,", e);
            return null;
        }
    }


    public static String encode(String content, String aesKey) {
        try {
            //生成和mysql一直的加密数据
            SecretKeySpec key = general(aesKey);
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, key);
            byte[] cleartext = content.getBytes(StandardCharsets.UTF_8);
            byte[] cipherTextBytes = cipher.doFinal(cleartext);
            return Base64.encodeBase64String(cipherTextBytes);
        } catch (Exception e) {
            log.error("Aes加解密异常encode,", e);
        }
        return null;
    }

    public static String encodeHex(String content, String aesKey) {
        try {
            //生成和mysql一直的加密数据
            SecretKeySpec key = general(aesKey);
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, key);
            byte[] cleartext = content.getBytes(StandardCharsets.UTF_8);
            byte[] cipherTextBytes = cipher.doFinal(cleartext);
            return Hex.encodeHexString(cipherTextBytes);
        } catch (Exception e) {
            log.error("Aes加解密异常encode,", e);
        }
        return null;
    }

    public static String decode(String content, String aesKey) {
        try {
            SecretKey key = generateMysqlAesKey(aesKey, StandardCharsets.UTF_8.name());
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, key);
            byte[] cleartext = Base64.decodeBase64(content);
            byte[] cipherTextBytes = cipher.doFinal(cleartext);
            return new String(cipherTextBytes, StandardCharsets.UTF_8);
        } catch (Exception e) {
            log.error("Aes加解密异常decode,", e);
            return null;
        }
    }

    public static String decodeHex(String content, String aesKey) {
        try {
            SecretKey key = generateMysqlAesKey(aesKey, StandardCharsets.UTF_8.name());
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, key);
            byte[] cleartext = Hex.decodeHex(content);
            byte[] cipherTextBytes = cipher.doFinal(cleartext);
            return new String(cipherTextBytes, StandardCharsets.UTF_8);
        } catch (Exception e) {
            log.error("Aes加解密异常decode,", e);
            return null;
        }
    }
}
